package com.ruoyi.littleRedBook.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.littleRedBook.domain.pojo.Coupon;
import com.ruoyi.littleRedBook.domain.pojo.ReceiveRecord;
import com.ruoyi.littleRedBook.mapper.CouponMapper;
import com.ruoyi.littleRedBook.mapper.ReceiveRecordMapper;
import com.ruoyi.littleRedBook.service.CouponService;
import com.ruoyi.littleRedBook.service.ReceiveRecordService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 优惠券表 服务实现类
 * </p>
 *
 * @author
 * @since
 */
@Service
public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> implements CouponService {

    @Resource
    private CouponMapper couponMapper;

    @Resource
    private ReceiveRecordMapper receiveRecordMapper;

    /**
     * 用户领取优惠券
     * 使用synchronized保证单机环境下的线程安全
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized ReceiveRecord receiveCoupon(Long userId, Long couponId) {
        // 参数校验
        Assert.notNull(userId, "用户ID不能为空");
        Assert.notNull(couponId, "优惠券ID不能为空");

        // 1. 查询优惠券信息
        Coupon coupon = couponMapper.selectById(couponId);
        Assert.notNull(coupon, "优惠券不存在");

        // 2. 检查优惠券是否已删除
        if (coupon.getIsDeleted() != null && coupon.getIsDeleted() == 1) {
            throw new RuntimeException("该优惠券已失效");
        }

        // 3. 检查是否超过最晚领取时间
        if (coupon.getLatestReceiveTime() != null &&
                LocalDateTime.now().isAfter(coupon.getLatestReceiveTime())) {
            throw new RuntimeException("已超过最晚领取时间");
        }

        // 4. 检查库存是否充足
        if (coupon.getStockQuantity() == null || coupon.getStockQuantity() <= 0) {
            throw new RuntimeException("优惠券已领完");
        }

        // 5. 检查用户已领取数量是否超过限制
        int receivedCount = receiveRecordMapper.selectCountByUserAndCoupon(userId, couponId);
        if (coupon.getPerPersonLimit() != null &&
                receivedCount >= coupon.getPerPersonLimit()) {
            throw new RuntimeException("已超过每人领取上限");
        }

        // 6. 扣减库存
        int affectRows = couponMapper.deductStock(couponId);
        if (affectRows <= 0) {
            throw new RuntimeException("领取失败，请重试");
        }

        // 7. 记录领取信息
        ReceiveRecord record = new ReceiveRecord();
        record.setUserId(userId);
        record.setCouponId(couponId);
        record.setCreateTime(LocalDateTime.now());
        receiveRecordMapper.insert(record);

        return record;
    }



    @Override
    public List<Coupon> getValidCoupons() {
        return couponMapper.selectValidCoupons();
    }

    @Override
    public List<Coupon> getCouponsByUserId(Long userId) {
        return couponMapper.selectByUserId(userId);
    }

    @Override
    public List<Coupon> listNotDeleted() {
        QueryWrapper<Coupon> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_deleted", 0);
        return baseMapper.selectList(queryWrapper);
    }

    @Override
    public List<Coupon> listDeleted() {
        QueryWrapper<Coupon> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_deleted", 1);
        return baseMapper.selectList(queryWrapper);
    }
}
